﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BuildPlannerLib.PlayerActions;
using BuildPlannerLib.SimEvents;
using BuildPlannerLib.Terran.Buildings;
using BuildPlannerLib.Terran.Enums;
using BuildPlannerLib.Terran.SimEvents;
using BuildPlannerLib.Buildings;

namespace BuildPlannerLib.Terran.PlayerActions
{
    // Derived class from Action for upgrading a Command Center to an Orbital Command
    public class UpgradeCC : PlayerAction
    {
        // Field for the Command Center that will be upgraded
        public IndividualCommandCenter CommandCenter;

        // CommandCenterUpgrade enum property for the type of upgrade
        private CommandCenterUpgrade upgrade;
        public CommandCenterUpgrade Upgrade
        {
            get { return upgrade; }
            set { upgrade = value; }
        }

        // String property for the requirement building
        private string requirement;
        public string Requirement
        {
            get { return requirement; }
            set { requirement = value; }
        }

        // Constructor with a parameter for the build
        public UpgradeCC(Build build, CommandCenterUpgrade upgrade)
        {
            Build = build;
            Upgrade = upgrade;
            string shortHand = "OC";
            switch (Upgrade)
            {
                case CommandCenterUpgrade.OrbitalCommand:
                    TimeDuration = 3500;
                    MineralCost = 150;
                    Requirement = "Barracks";
                    break;
                case CommandCenterUpgrade.PlanetaryFortress:
                    TimeDuration = 5000;
                    MineralCost = 150;
                    GasCost = 150;
                    Requirement = "Engineering Bay";
                    shortHand = "PF";
                    break;
            }
            Description = "Upgrade CC to " + shortHand;
            LongDescription = "Upgrading existing Command Center into a " + Upgrade + ".";
        }

        // Evaluates whether the player is Terran, whether there is mineral income or enough minerals, and whether an un-upgraded CC exists
        public override bool RequirementsFilled()
        {
            CommandCenter commandCenter = Build.Player.MainBuilding as CommandCenter;
            Error = null;

            if (commandCenter == null)
            {
                Error = "This building can only be built by Terran players.";
                return false;
            }

            bool availableCommandCenter = commandCenter.IndividualMainBuildings.Exists(delegate(IndividualMainBuilding i)
            {
                IndividualCommandCenter c = i as IndividualCommandCenter;
                return c.UpgradeStatus == CommandCenterUpgrade.BasicCC;
            });
            if (!availableCommandCenter)
            {
                Error = "No un-upgraded Command Centers available.";
                return false;
            }

            if (Upgrade != CommandCenterUpgrade.OrbitalCommand && Upgrade != CommandCenterUpgrade.PlanetaryFortress)
            {
                Error = "Invalid upgrade type.";
                return false;
            }

            if (Build.Player.GetBuilding(Requirement).Started == 0)
            {
                Error = "The required building \"" + Requirement + "\" has not been built.";
                return false;
            }

            return base.RequirementsFilled();
        }

        // Evaluates if enough minerals are available and an un-upgraded CC is not in-use
        public override bool StartCheck()
        {
            CommandCenter commandCenter = Build.Player.MainBuilding as CommandCenter;

            bool availableCommandCenter = commandCenter.IndividualMainBuildings.Exists(delegate(IndividualMainBuilding i)
            {
                IndividualCommandCenter c = i as IndividualCommandCenter;
                return c.UpgradeStatus == CommandCenterUpgrade.BasicCC && !i.InUse && !c.Floating;
            });
            if (!availableCommandCenter)
                return false;

            if (Build.Player.GetBuilding(Requirement).GetCount() == 0)
                return false;
            
            return base.StartCheck();
        }

        // Spends the minerals, sets the Command Center to Converting status, and adds the event for finishing the action
        public override void StartAction()
        {
            CommandCenter commandCenter = Build.Player.MainBuilding as CommandCenter;

            base.StartAction();

            CommandCenter = commandCenter.IndividualMainBuildings.Find(delegate(IndividualMainBuilding i)
            {
                IndividualCommandCenter c = i as IndividualCommandCenter;
                return (!i.InUse && !c.Floating && c.UpgradeStatus == CommandCenterUpgrade.BasicCC);
            }) as IndividualCommandCenter;

            CommandCenter.StartConvert(Upgrade);
        }

        // Sets the Command Center to OrbitalCommand status, adds the event for the first MULE calldown, and adds the event for the first energy tick
        public override void FinishAction()
        {
            base.FinishAction();

            CommandCenter.FinishConvert(Upgrade);
            if (Upgrade == CommandCenterUpgrade.OrbitalCommand)
            {
                Build.EventList.Add(new MULECalldown(Build, CommandCenter, TimeConvert.ToInt(Build.CurrentTime)));
                int newTime = TimeConvert.ToInt(Build.CurrentTime) + 444;
                Build.EventList.Add(new OCEnergyTick(Build, CommandCenter, newTime));
            }
        }
    }
}
